<template>
  <view class="content">
    <div class="main-container">
      <!-- 左侧控制面板 -->
      <div class="control-panel left-panel">
        <uni-section title="图片素材" type="line" padding>
          <div class="section-content">
            <uni-tag text="本地图片" type="primary" @click="chooseImg()" class="control-btn full-width">本地图片</uni-tag>
            <div class="network-img-input">
              <uni-easyinput
                  v-model="imgUrl"
                  placeholder="请输入图片地址"
                  confirmType="done"
                  suffix-icon="cloud-upload"
                  @iconClick="bindImg"
                  class="img-input"
              />
            </div>
          </div>
        </uni-section>

        <uni-section title="文字编辑" type="line" padding>
          <div class="section-content">
            <uni-easyinput
                styles="width: 100%;"
                v-model="text"
                placeholder="请输入文字内容"
                type="textarea"
                autoHeight
                confirmType="done"
                suffix-icon="cloud-upload"
                @input="bindChangeText"
                @iconClick="bindText"
                class="text-input"
            />
            <div class="text-controls">
              <view class="controls-grid">
                <view class="tag-view">
                  <uni-tag text="横向排列" type="primary" @click="updateText('horizontal', 'horizontal')" />
                </view>
                <view class="tag-view">
                  <uni-tag text="竖向排列" type="primary" @click="updateText('vertical', 'vertical')"/>
                </view>
                <view class="tag-view">
                  <uni-tag text="文字描边" type="primary" @click="updateText('lineWidth', '2')"/>
                </view>
                <view class="tag-view">
                  <uni-tag text="加粗" type="primary" @click="updateText('fontWeight', 'bold')"/>
                </view>
                <view class="tag-view">
                  <uni-tag text="斜体" type="primary" @click="updateText('fontStyle', 'italic')"/>
                </view>
                <view class="tag-view">
                  <uni-tag text="下划线" type="primary" @click="updateText('underline', 'underline')"/>
                </view>
                <view class="tag-view">
                  <uni-tag text="textAlign" type="primary" @click="updateText('', 'x')"/>
                </view>
                <view class="tag-view">
                  <uni-tag text="textBaseline" type="primary" @click="updateText('', 'x')"/>
                </view>
                <view class="tag-view">
                  <uni-tag text="文字颜色" type="primary" @click="updateText('fillStyle', `#${Math.floor(Math.random()*16777215).toString(16).padStart(6, '0')}`)"/>
                </view>
              </view>
            </div>
          </div>
        </uni-section>
      </div>

      <!-- 中间画布区域 -->
      <div class="canvas-container">
        <canvas
            ref="canvasRef"
            class="main-canvas"
            id="firstCanvas"
            @mousedown="bindTouchstart"
            @mousemove="bindTouchmove"
            @mouseup="bindTouchend"
        />
      </div>

      <!-- 右侧控制面板 -->
      <div class="control-panel right-panel">
        <uni-section title="操作控制" type="line" padding>
          <div class="section-content">
            <div class="control-group">
              <h4>方向调整</h4>
              <view class="example-body controls-row">
                <view class="tag-view">
                  <uni-tag text="水平翻转" type="primary" @click="changeDirection('x')" />
                </view>
                <view class="tag-view">
                  <uni-tag text="垂直翻转" type="primary" @click="changeDirection('y')"/>
                </view>
                <view class="tag-view">
                  <uni-tag text="复制" type="primary" @click="copy('copy')"/>
                </view>
              </view>
            </div>

            <div class="control-group">
              <h4>图层管理</h4>
              <view class="example-body controls-row">
                <view class="tag-view">
                  <uni-tag text="置顶" type="primary" @click="changeZIndex('top')" />
                </view>
                <view class="tag-view">
                  <uni-tag text="上移" type="primary" @click="changeZIndex('up')"/>
                </view>
                <view class="tag-view">
                  <uni-tag text="下移" type="primary" @click="changeZIndex('down')"/>
                </view>
                <view class="tag-view">
                  <uni-tag text="置底" type="primary" @click="changeZIndex('bottom')" />
                </view>
              </view>
            </div>

            <div class="control-group">
              <h4>历史记录</h4>
              <view class="example-body controls-row">
                <view class="tag-view">
                  <uni-tag text="撤销" type="primary" @click="changeHistory('pre')" />
                </view>
                <view class="tag-view">
                  <uni-tag text="重做" type="primary" @click="changeHistory('next')"/>
                </view>
              </view>
            </div>
          </div>
        </uni-section>
      </div>
    </div>

    <!-- 底部图层预览区域 -->
    <div class="layer-preview-container">
      <uni-section title="图层预览" type="line" padding>
        <div class="layer-preview-content">
          <template v-for="(img, index) in images" :key="index">
            <image mode="aspectFit" :src="img" @click="bindPreview(index)" class="preview-image"></image>
          </template>
        </div>
      </uni-section>
    </div>
  </view>
</template>


<script setup lang="ts">
import {
  ref,
  onMounted, shallowRef
} from 'vue';
import {ImageNode, ImageNodeBox, Placard, PlacardTools, RotateControl, ScaleControl, TextNodeBox, TextNode} from "../../../../canvas-test/dist/index.js";
import {DeleteControl, ReplaceControl} from "../../../../canvas-test";

// 创建一个 ref 来引用 canvas 元素
const canvasRef = ref(null);
let placard: Placard;

onMounted(() => {
  // 使用新版 Canvas API
  const query = uni.createSelectorQuery();
  query
      .select('#firstCanvas')
      .fields({
        node: true,
        size: true
      })
      .exec((res) => {
        if (res[0]) {
          const canvas = res[0].node;
          const ctx = canvas.getContext('2d');
          // 处理高DPI屏幕，使绘制更清晰
          const dpr = uni.getSystemInfoSync().pixelRatio;
          canvas.width = res[0].width * dpr;
          canvas.height = res[0].height * dpr;
          ctx.scale(dpr, dpr);

          placard = new Placard({
            canvas: canvas,
            canvasWidth: 400,
            canvasHeight: 500,
            backgroundColor: "#000000",
          })
          const renderReact = placard.getRenderReact();
          const scaleControl = new ScaleControl(renderReact);
          const rotateControl = new RotateControl(renderReact);
          const deleteControl = new DeleteControl(renderReact, {event: {
              down: (point, node) => {
                console.log('onDelete', {node, point})
                uni.showToast({
                  title: `你点击了《 ${node.id} 》节点的删除按钮`,
                  icon: 'none',
                  duration: 2000
                })
                placard.removeNode(node.id)
                placard.renderDraw()
              }
            }});
          const replaceControl = new ReplaceControl(renderReact,
              {event: {
                  down: (point, node) => {
                    console.log('replace', {node, point})
                    uni.showToast({
                      title: `你点击了《 ${node.id} 》节点的替换按钮`,
                      icon: 'none',
                      duration: 2000
                    })
                    chooseImg('replace')
                  }
                }});

          placard.loadControl([scaleControl, rotateControl, deleteControl, replaceControl]);
          window._placard = placard;


          placard.on('rendered', () => {
            console.log('rendered')
            showCanvasImage()
          })
        }
      });
});

const chooseImg = (type = '') => {
  uni.chooseImage({
    count: 1,
    sizeType: ['original', 'compressed'],
    sourceType: ['album', 'camera'],
    success: async (res) => {
      const tempFilePath = res.tempFilePaths[0];
      const base64 = await PlacardTools.imageToBase64(tempFilePath)
      const img = new Image();
      img.src = `${base64}`;
      img.onload = () => {

        const imageNode = new ImageNode({
          data: img,
          width: 200,
          height: 200,
          url: tempFilePath,
          scale: 1,
          base64
        })
        if(type === 'replace') {
          const selectNode = placard!.canvasEvent.getSelectNode();
          if(selectNode && selectNode.getType() === 'img') {
            selectNode.replaceImage(imageNode)
            selectNode.drawCache();
          }
        }else {
          const imageNodeBox = new ImageNodeBox(imageNode, placard!.getRenderReact())
          imageNodeBox.setMode('aspectFit', {maxWidth: 200, maxHeight: 200})
          imageNodeBox.drawCache();
          placard.addNode(imageNodeBox)
        }

        placard.renderDraw()
      }

    }
  })
}

let isStart = false;
const bindTouchstart = (e: any) => {
  // console.log('bindTouchstart', e)
  isStart = true;
  placard!.canvasEvent.down(e)

  const selectNode = placard!.canvasEvent.getSelectNode();
  if(selectNode && selectNode.getType() === 'text') {
    text.value = selectNode._textNode.text;
  }
}
const bindTouchmove = (e: any) => {
  isStart && placard!.canvasEvent.move(e)
}
const bindTouchend = (e: any) => {
  // console.log('bindTouchend', e)
  placard!.canvasEvent.up(e);
  isStart = false;
}

const imgUrl = ref('https://www.baidu.com/img/flexible/logo/pc/result.png')
const bindImg = (e) => {
  console.log('bindImg', imgUrl.value)
  if(imgUrl.value.indexOf('http') !== 0) {
    uni.showLoading({
      title: '非法图片链接',
      mask: true
    })
    return;
  }
  ImageNode.createImageData(imgUrl.value).then( async (img) => {
    console.log('createImageData', img)
    const base64Data = await PlacardTools.imageToBase64(img.src);
    const imageNode = new ImageNode({
      data: img,
      width: img.width,
      height: img.height,
      url: imgUrl.value,
      scale: 1,
      base64: base64Data
    })

    const imageNodeBox = new ImageNodeBox(imageNode, placard!.getRenderReact())
    imageNodeBox.setMode('aspectFit', {maxWidth: 200, maxHeight: 200})
    imageNodeBox.isSelected = true;
    imageNodeBox.drawCache();
    placard.addNode(imageNodeBox)
    placard.renderDraw()
  });
}


const changeZIndex = (type: 'top' | 'up' | 'down' | 'bottom') => {
  const selectNodeBox = placard.canvasEvent.getSelectNode();
  if (!selectNodeBox) return;
  placard.reorderZIndexNode(selectNodeBox, type);
  placard.renderDraw();
}

const changeDirection = (type: 'x' | 'y') => {
  const selectNodeBox = placard.canvasEvent.getSelectNode();
  if (!selectNodeBox) return;
  selectNodeBox.flip(type);
  selectNodeBox.drawCache();
  placard.renderDraw();
}
const copy = async (type: 'copy') => {
  const copyNode = placard.canvasEvent.getSelectNode()?.copy();
  if (!copyNode) {
    uni.showLoading({
      title: '请选择节点',
      mask: true
    })
    return
  };
  console.log('copyNode', copyNode)
  if(copyNode.getType() === 'img') {
    await ImageNode.createImageData(copyNode._imageNode.base64)
        .then((img) => {
          const copyImageNode = copyNode._imageNode.copy();
          copyImageNode.replaceImageData(img)
          copyNode.replaceImage(copyImageNode)
        })
        .catch(error => {
          console.error('Failed to load image:', error);
        })
  }
  // 左下偏移20
  copyNode?.shapeReact?.useMove(20, 20);
  copyNode?.drawCache();
  placard.addNode(copyNode)
  placard.canvasEvent.setSelectNode(copyNode)
  placard.renderDraw()
}

const text = ref('测试文字\n12345678910\n1234s试试')
const bindChangeText = async () => {
  const selectNodeBox = placard.canvasEvent.getSelectNode();
  console.log('bindChangeText',text.value, selectNodeBox,)
  if (selectNodeBox?.getType() === 'text') {
    selectNodeBox.updateAttribute('text', text.value);
    await selectNodeBox.drawCache();
  }
  placard.renderDraw()
}
const bindText = () => {
  if(!text.value) return
  const selectNodeBox = placard.canvasEvent.getSelectNode();
  console.log('selectNodeBox', selectNodeBox)
  if (selectNodeBox?.getType() === 'text') {
    selectNodeBox.updateAttribute('text', text.value);
    selectNodeBox.drawCache();
  }else {
    const textNode = new TextNode({
      text: text.value,
      fontSize: 20,
      color: 'red',
    })
    const textNodeBox = new TextNodeBox(textNode, placard!.getRenderReact())
    textNodeBox.setLocation('center')
    textNodeBox.drawCache()
    placard.addNode(textNodeBox)
    text.value = '';
  }
  placard.renderDraw()
}

const updateText = (key: string, value: string) => {
  const selectNodeBox = placard.canvasEvent.getSelectNode();
  if (!selectNodeBox) return;
  if(['horizontal', 'vertical'].includes(key)) {
    selectNodeBox.changeDirection(value); // 这应该可以工作了
  }else if(['lineWidth'].includes(key)) {
    const newValue = selectNodeBox.getAttribute(key) === value ? '' : value;
    selectNodeBox.updateAttribute(key, newValue);
  }else if(['fontWeight'].includes(key)) {
    const newValue = selectNodeBox.getAttribute(key) === value ? '' : value;
    selectNodeBox.updateAttribute(key, newValue);
  }else if(['fillStyle'].includes(key)) {
    const newValue = selectNodeBox.getAttribute(key) === value ? '' : value;
    selectNodeBox.updateAttribute(key, newValue);
  }else if (['underline'].includes(key)) {
    const textDecorationValues = ['underline', 'line-through', 'overline', ''].sort((a, b) => Math.random() - 0.5);
    updateTextAttribute('textDecoration', textDecorationValues[0]);
    updateTextAttribute('textDecorationColor', `#${Math.floor(Math.random()*16777215).toString(16).padStart(6, '0')}`);
  }
  selectNodeBox.drawCache();
  placard.renderDraw()
}


const changeHistory = (type: 'pre' | 'next') => {
  let historyItem;
  if(type ==='pre') {
    historyItem = placard.historyTask.undo()
  }else {
    historyItem = placard.historyTask.redo()
  }
  if(historyItem) {
    placard.resetNodeList(historyItem.historyNodeBoxList)
    placard.renderDraw(false)
  }
}


const images = shallowRef<Array<string>>([])
const showCanvasImage = async () => {
  const nodes = placard.getNodeList();
  const imagList: Array<string> = [];
  for (const node of nodes) {
    console.log('node', node)
    const img = await node.exportCanvasDataImg();
    imagList.push(img)
  }
  images.value = imagList
}

const bindPreview = () => {
  uni.previewImage({
    urls: images.value,
  })
}

</script>

<style lang="scss" scoped>
.content {
  padding: 20rpx;
  height: calc(100vh - 44px);
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
}

.main-container {
  display: flex;
  flex: 1;
  gap: 20rpx;
  margin-bottom: 20rpx;
  min-height: 0; /* 允许容器收缩 */
}

.control-panel {
  flex: 0 0 450rpx; /* 固定宽度，不伸缩 */
  background: #f8f8f8;
  border-radius: 10rpx;
  padding: 15rpx;
  overflow-y: auto;
  box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.1);

  .section-content {
    margin-top: 15rpx;
  }

  .control-btn.full-width {
    width: 100%;
    margin-bottom: 15rpx;
  }

  .network-img-input {
    margin-top: 15rpx;
  }

  .img-input, .text-input {
    margin-bottom: 15rpx;
  }

  .controls-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 30rpx;
  }

  .control-group {
    margin-bottom: 20rpx;

    h4 {
      margin: 0 0 10rpx 0;
      font-weight: bold;
      color: #333;
      font-size: 28rpx;
    }
  }

  .controls-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8rpx;

    .tag-view {
      flex: 1;
      min-width: 70rpx;
    }
  }
}

.canvas-container {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #f0f0f0;
  border-radius: 10rpx;
  padding: 15rpx;
  box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.1);
  min-height: 0; /* 允许容器收缩 */
}

.main-canvas {
  width: 100%;
  height: 100%;
  max-width: 500rpx; /* 减小最大宽度 */
  max-height: 600rpx; /* 减小最大高度 */
  border: 2rpx solid #7a7272;
  background: white;
  box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.15);
}

/* 底部图层预览样式 */
.layer-preview-container {
  background: #f8f8f8;
  border-radius: 10rpx;
  padding: 15rpx;
  box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.1);
  flex-shrink: 0; /* 防止压缩 */

  .layer-preview-content {
    display: flex;
    flex-wrap: wrap;
    gap: 15rpx;
    margin-top: 15rpx;
    max-height: 120rpx; /* 限制高度 */
    overflow-x: auto; /* 水平滚动 */

    .preview-image {
      width: 100rpx;
      height: 100rpx;
      border: 1rpx solid #ddd;
      border-radius: 5rpx;
      flex-shrink: 0; /* 防止压缩 */
    }
  }
}

@media screen and (max-width: 768px) {
  .main-container {
    flex-direction: column;
    height: auto;
  }

  .control-panel {
    max-width: 100%;
    order: 2;
  }

  .canvas-container {
    order: 1;
    padding: 10rpx;
  }

  .main-canvas {
    max-width: 100%;
    max-height: 500rpx;
  }

  .controls-grid {
    grid-template-columns: repeat(3, 1fr);
  }

  .layer-preview-content {
    justify-content: flex-start;
  }
}
</style>

